package com.shop2cn.iapi.sqoptrade.parameter.model.placeorder;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.shop2cn.iapi.sqoptrade.parameter.utill.Utils;
import com.shop2cn.iapi.sqoptrade.parameter.vo.CatalogApportionVo;
import com.shop2cn.iapi.sqoptrade.parameter.vo.OrderGroupVo;
import com.shop2cn.iapi.sqoptrade.parameter.vo.SellerPromotionVo;
import com.ymt.core.tool.Logger;

/**
 *
 */
public class OrderGroup {

	private OrderGroupVo orderGroupVo;

	// 该卖家的所有订单
	private List<Order> orders = new ArrayList<Order>();

	// 订单组下各订单关于商家优惠券的权重
	private List<BigDecimal> orderWeightsOnSellerCoupon = new ArrayList<BigDecimal>();
	
	// 订单组下各订单关于区域折扣的权重
	private List<BigDecimal> orderWeightsOnRegionDiscount = new ArrayList<BigDecimal>();
	
	// 订单组享受的区域折扣总额
	private BigDecimal regionDiscount;

	public List<Order> getOrders() {
		return orders;
	}

	public void setOrders(List<Order> orders) {
		this.orders = orders;
	}

	public List<BigDecimal> getOrderWeightsOnSellerCoupon() {
		return orderWeightsOnSellerCoupon;
	}

	public void setOrderWeightsOnSellerCoupon(
			List<BigDecimal> orderWeightsOnSellerCoupon) {
		this.orderWeightsOnSellerCoupon = orderWeightsOnSellerCoupon;
	}

	public BigDecimal[] calcMaxPromotionsLeft() {
		List<BigDecimal> result = new ArrayList<BigDecimal>();
		for (Order o : orders) {
			result.add(o.calcMaxPromotionLeft());
		}
		return result.toArray(new BigDecimal[0]);
	}

	public OrderGroupVo getOrderGroupVo() {
		return orderGroupVo;
	}

	public void setOrderGroupVo(OrderGroupVo orderGroupVo) {
		this.orderGroupVo = orderGroupVo;
	}
	
	public List<BigDecimal> getOrderWeightsOnRegionDiscount() {
		return orderWeightsOnRegionDiscount;
	}

	public void setOrderWeightsOnRegionDiscount(
			List<BigDecimal> orderWeightsOnRegionDiscount) {
		this.orderWeightsOnRegionDiscount = orderWeightsOnRegionDiscount;
	}

	public BigDecimal getRegionDiscount() {
		return regionDiscount;
	}

	public void setRegionDiscount(BigDecimal regionDiscount) {
		this.regionDiscount = regionDiscount;
	}

	/**
	 * 将商家优惠分配到各个订单项
	 */
	public void distributeSellerPromotionApportions() {
		this.distributeSellerPromotionApportions(null);
	}

	/**
	 * 将商家优惠分配到各个订单项
	 */
	public void distributeSellerPromotionApportions(String currency) {
		if (orderGroupVo.getSellerPromotionApportions() != null) {
			for (SellerPromotionVo p : orderGroupVo
					.getSellerPromotionApportions()) {
				if (p.getQtyCondition() <= 0
						&& (p.getAmountCondition() == null || p
								.getAmountCondition()
								.compareTo(BigDecimal.ZERO) <= 0)) {
					throw new IllegalArgumentException("卖家优惠活动条件未提供:"
							+ p.getId());
				}

				// 该优惠应用到订单项
				List<OrderItemApportionNum> itemApportions = new ArrayList<OrderItemApportionNum>();
				for (CatalogApportionVo c : p.getApportions()) {
					boolean matched = false;
					
					int count = c.getCount();
					
					for (Order o : orders) {
						if (matched) {
							break;
						}
						
						for (OrderItem item : o.getOrderItems()) {
							
							// 带分摊优惠的商品数量
							int num = item.getItemVo().getProductNum()
									- item.countPromotionProductNum();
							
							if (item.getItemVo().getCatalogId()
									.equals(c.getCatalogId())
									&& !Utils.falseIfNull(item.getItemVo()
											.getExchangeBuy())) {
								
								if (num >= count) {
									item.getCatalogApportionVos().add(c);
									
									// 一个商品同一时刻只享受一次优惠活动，各活动信息是一致的,选取最后一个
									item.setSellerPromotion(p);
									itemApportions.add(new OrderItemApportionNum(
											item, count));

									matched = true;
									break;
								} else {
									
									count = count - item.getItemVo().getProductNum();
									item.getCatalogApportionVos().add(c);

									// 一个商品同一时刻只享受一次优惠活动，各活动信息是一致的,选取最后一个
									item.setSellerPromotion(p);
									itemApportions.add(new OrderItemApportionNum(
											item, item.getItemVo().getProductNum()));

									break;
								}
							}
						}
					}
				}

				if (itemApportions.size() > 0) {
					// 订单项关于该优惠的权重
					List<BigDecimal> weights = new ArrayList<BigDecimal>();
					List<BigDecimal> maxLimits = new ArrayList<BigDecimal>();

					for (OrderItemApportionNum itemApportion : itemApportions) {
						
						if (!Utils.falseIfNull(itemApportion.orderItem
								.getItemVo().getExchangeBuy())) {
							
							weights.add(itemApportion.orderItem
									.getItemVo()
									.getProductPrice()
									.multiply(
											new BigDecimal(
													itemApportion.apportionNum)));
							maxLimits.add(itemApportion.orderItem
									.calcMaxPromotionLeft());
						} else {
							
							weights.add(BigDecimal.ZERO);
							maxLimits.add(itemApportion.orderItem
									.calcMaxPromotionLeft());
						}
					}
					
					BigDecimal[] apportions = null;

					Logger.info(String.format("优惠分摊数据：total:%s, weights:%s, currency:%s",
							p.getReducedAmount(), weights, currency));

					if (null == currency) {
						
						apportions = Utils
								.apportionByWeightsWithCurrency(
										p.getReducedAmount(),
										weights.toArray(new BigDecimal[0]),
										//maxLimits.toArray(new BigDecimal[0])
										 currency);
					} else {
						
						apportions = Utils
								.apportionByWeightsWithCurrency(
										p.getReducedAmount(),
										weights.toArray(new BigDecimal[0]),
										//maxLimits.toArray(new BigDecimal[0])
										 currency);
					}

					int i = 0;

					for (OrderItemApportionNum itemApportion : itemApportions) {
						if (apportions[i].compareTo(BigDecimal.ZERO) > 0) {
							itemApportion.orderItem
									.setSellerPromotionAmount(Utils
											.zeroIfNull(
													itemApportion.orderItem
															.getSellerPromotionAmount())
											.add(apportions[i]));
						}
						
						i++;
					}
				}
			}

			for (Order o : orders) {
				BigDecimal sum = BigDecimal.ZERO;

				for (OrderItem item : o.getOrderItems()) {
					sum = sum.add(Utils.zeroIfNull(item
							.getSellerPromotionAmount()));
				}

				o.setSellerPromotionAmount(sum);
			}
		}
	}

	private static class OrderItemApportionNum {
		public OrderItem orderItem;
		public int apportionNum;
		public OrderItemApportionNum(OrderItem orderItem, int apportionNum) {
			this.orderItem = orderItem;
			this.apportionNum = apportionNum;
		}
	}
}
